package max.ta.data.plot;

import java.text.SimpleDateFormat;
import java.util.Date;

import max.ta.data.Function;
import max.ta.data.plot.data.MathLine;
import max.ta.data.plot.data.MathPoint;
import max.ta.data.plot.data.MathSurface;
import max.ta.data.plot.gen.TimeSerieDataGenerator;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.data.time.Day;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;

public class TimeSeriesChartPlotter
	extends AbstractChartPlotter<Date, Double> {

    private static final long serialVersionUID = 1L;
    // ----------------------------------------------------------------------------------------
    // Axis
    // ----------------------------------------------------------------------------------------
    private static final SimpleDateFormat FORMATTER = new SimpleDateFormat("dd-MM-yyyy");
    private static final DateAxis DOMAIN_AXIS = new DateAxis("x");
    private static final NumberAxis RANGE_AXIS = new NumberAxis("y");

    public TimeSeriesChartPlotter(final String title) {
	super(title, DOMAIN_AXIS, RANGE_AXIS);
	DOMAIN_AXIS.setDateFormatOverride(FORMATTER);
    }

    @Override
    public void plot(String serieName, Function<Date, Double> fx, Date minX, Date maxX) {
	final TimeSerieDataGenerator generator = new TimeSerieDataGenerator(fx, minX, maxX);
	plot(serieName, generator.generate());
    }

    @Override
    protected JFreeChart createChart(MathSurface<Date, Double> points) {
	final TimeSeriesCollection dataset = createDataset(points);
	return ChartFactory.createTimeSeriesChart(title, X_LABEL, Y_LABEL, dataset, LEGEND, TOOLTIPS, URL);
    }

    private TimeSeriesCollection createDataset(MathSurface<Date, Double> points) {
	final TimeSeriesCollection dataset = new TimeSeriesCollection();
	for (MathLine<Date, Double> pointSet : points.getElements()) {
	    TimeSeries s = createDataSerie(pointSet);
	    dataset.addSeries(s);
	}
	return dataset;
    }

    private TimeSeries createDataSerie(MathLine<Date, Double> pointSet) {
	final TimeSeries s1 = new TimeSeries(pointSet.getName());
	for (MathPoint<Date, Double> p : pointSet.getElements()) {
	    s1.add(new Day(p.getX()), p.getY());
	}
	return s1;
    }
}
